﻿using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Neturion.Dados;
using Neturion.IRepositorios;

namespace Neturion.Repositorios
{
    public class RepositorioBanco : IRepositorioBanco
    {
        public Banco Inserir(Banco banco)
        {
            banco.FimVigencia = banco.FimVigencia.HasValue
                                    ? banco.FimVigencia.GetValueOrDefault().Date
                                    : banco.FimVigencia;
            banco.InicioVigencia = banco.InicioVigencia.HasValue
                                        ? banco.InicioVigencia.GetValueOrDefault().Date
                                        : banco.InicioVigencia;
            foreach (Agencia agencia in banco.ListaAgencias)
            {
                agencia.Banco = banco;
            }

            GerenciadorBDConfigs.Instance.SessaoAtual().Save(banco);
            return banco;
        }

        public Banco Atualizar(Banco banco)
        {
            Banco tmpBanco = ObterPorId(banco.BancoId);
            // Atribuicao dos valores do objeto da memoria para o objeto obtido no banco de dados
            tmpBanco.CodigoCompensacao = banco.CodigoCompensacao;
            tmpBanco.Descricao = banco.Descricao;
            tmpBanco.FimVigencia = banco.FimVigencia.HasValue
                                    ? banco.FimVigencia.GetValueOrDefault().Date
                                    : banco.FimVigencia;
            tmpBanco.InicioVigencia = banco.InicioVigencia.HasValue
                                        ? banco.InicioVigencia.GetValueOrDefault().Date
                                        : banco.InicioVigencia;
            tmpBanco.HomePage = banco.HomePage;
            tmpBanco.NeturionLog = banco.NeturionLog;
            tmpBanco.ListaAgencias.Clear();
            foreach (Agencia agencia in banco.ListaAgencias)
            {
                tmpBanco.AdicionarAgencia(agencia);
            }

            GerenciadorBDConfigs.Instance.SessaoAtual().Merge(tmpBanco);
            return tmpBanco;
        }

        public void Excluir(Banco banco)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Delete(banco);
        }

        public IList<Banco> ObterTodos()
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Banco));
            return criteria.List<Banco>() as List<Banco>;
        }

        public Banco ObterPorId(int id)
        {
            return GerenciadorBDConfigs.Instance.SessaoAtual().Get<Banco>(id);
        }

        public IList<Banco> ObterPorDescricao(string descricao)
        {
            ICriteria criteria =
               GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Banco)).Add(
                   Restrictions.Like("Descricao", descricao, MatchMode.Anywhere));
            return criteria.List<Banco>() as List<Banco>;
        }

        public IList<Banco> ObterTodos(int inicio, int quantidade, int quantidadeMinima, string codigoCompensacao, string descricao, DateTime? inicioDeVigenciaDe, DateTime? inicioDeVigenciaAte, DateTime? fimDeVigenciaDe, DateTime? fimDeVigenciaAte)
        {
            if (quantidade.Equals(0))
            {
                quantidade = quantidadeMinima;
            }

            IList<Banco> list;
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Banco))
               .SetFirstResult(inicio).SetMaxResults(quantidade);

            if (!string.IsNullOrEmpty(codigoCompensacao))
            {
                criteria.Add(Restrictions.Like("CodigoCompensacao", codigoCompensacao, MatchMode.Anywhere));
            }

            if (!string.IsNullOrEmpty(descricao))
            {
                criteria.Add(Restrictions.Like("Descricao", descricao, MatchMode.Anywhere));
            }

            if (inicioDeVigenciaDe.HasValue)
            {
                criteria.Add(inicioDeVigenciaAte.HasValue
                    ? Restrictions.Between("InicioVigencia", inicioDeVigenciaDe.Value.Date, inicioDeVigenciaAte.Value.Date)
                    : Restrictions.Eq("InicioVigencia", inicioDeVigenciaDe.Value.Date));
            }

            if (fimDeVigenciaDe.HasValue)
            {
                criteria.Add(fimDeVigenciaAte.HasValue
                    ? Restrictions.Between("FimVigencia", fimDeVigenciaDe.Value.Date, fimDeVigenciaAte.Value.Date)
                    : Restrictions.Eq("FimVigencia", fimDeVigenciaDe.Value.Date));
            }

            list = criteria.List<Banco>() as List<Banco>;
            
            return list;
        }

        public IList<Banco> ObterPorCodigo(string codigo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(Banco))
                .Add(Restrictions.Eq("CodigoCompensacao", codigo));

            return criteria.List<Banco>() as List<Banco>;
        }

        #region IRepositorioBanco Members

        #endregion
    }
}